项目瘦身:自动路由、布局及vite配置拆分
概述
将 base 模板项目中的可选功能模块拆分为独立配置包,使模板项目保持精简。本节重点拆分 layouts(布局)、router(自动路由)、auto-import(自动导入)等 Vite 配置,形成可插拔的 config 目录结构,让用户可以按需选择需要的功能模块。
拆分目标结构
templates/
├── base/ # 基础模板(最小可用)
│ ├── config/ # 配置目录
│ │ ├── base/ # 基础 Vite 配置
│ │ │ └── vite.config.base.ts
│ │ ├── layout/ # 布局模块配置
│ │ │ ├── vite.config.ts
│ │ │ ├── package.json
│ │ │ └── src/
│ │ │ └── layout/
│ │ ├── router/ # 自动路由配置
│ │ │ ├── vite.config.ts
│ │ │ └── package.json
│ │ └── cdn/ # CDN 配置
│ │ └── vite.config.ts
│ ├── src/
│ ├── package.json
│ └── vite.config.ts # 合并后的最终配置
text
拆分步骤
1. 拆分 Layouts 模块
将 vite.config.ts 中与 layouts 相关的配置和依赖提取到 config/layout/ 下:
// config/layout/vite.config.ts
import Layouts from 'vite-plugin-vue-layouts'
export function getLayoutConfig() {
return {
plugins: [
Layouts({
layoutsDirs: 'src/layout',
defaultLayout: 'default',
}),
],
}
}
ts
// config/layout/package.json
{
"dependencies": {
"vite-plugin-vue-layouts": "^0.11.0"
}
}
json
同步提取布局组件到 config/layout/src/layout/ 目录,这样模板 CLI 在选择 layouts 功能时可以一并拷贝布局组件文件。
2. 拆分 Router 模块
将自动路由相关配置提取到 config/router/ 下:
// config/router/vite.config.ts
import VueRouter from 'unplugin-vue-router/vite'
export function getRouterConfig() {
return {
plugins: [
VueRouter({
routesFolder: 'src/pages',
dts: 'typed-router.d.ts',
}),
],
}
}
ts
路由模块移除 layouts 依赖后,直接使用 createRouter 创建路由:
// 移除前(依赖 vite-ssg,与 layouts 强绑定)
import { ViteSSG } from 'vite-ssg'
// 移除后(独立路由,不依赖 layouts)
import { createRouter, createWebHistory } from 'vue-router'
ts
注意:当路由和 layouts 需要整合在一起时,需要把与 layouts 相关联的部分也一并整合到路由模块中,这就需要合并操作。
3. 拆分 Auto-Import 配置
// config/auto-import/vite.config.ts
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
export function getAutoImportConfig() {
return {
plugins: [
AutoImport({
imports: ['vue', 'vue-router'],
dts: 'auto-imports.d.ts',
}),
Components({
dirs: ['src/components'],
dts: 'components.d.ts',
}),
],
}
}
ts
4. Base 配置文件
// config/base/vite.config.base.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
resolve: {
alias: {
'@': '/src',
},
},
})
ts
配置合并策略
Vite 提供了 mergeConfig 工具函数,可以深度合并两个配置对象。最终 vite.config.ts 通过合并函数组合各模块配置:
// vite.config.ts
import { defineConfig, mergeConfig } from 'vite'
import { getLayoutConfig } from './config/layout/vite.config'
import { getRouterConfig } from './config/router/vite.config'
import { getAutoImportConfig } from './config/auto-import/vite.config'
import baseConfig from './config/base/vite.config.base'
export default defineConfig(({ mode }) => {
let config = { ...baseConfig }
// 始终引入路由
config = mergeConfig(config, getRouterConfig())
// 按需引入 Layout 模块
if (mode !== 'simple') {
config = mergeConfig(config, getLayoutConfig())
}
// 自动导入
config = mergeConfig(config, getAutoImportConfig())
return config
})
ts
手动合并方式(适用于模板 CLI)
模板 CLI 生成项目时,需要手动合并插件数组:
// scripts/merge-config.ts
export function mergeViteConfigs(
configs: Array<() => { plugins: any[]; [key: string]: any }>
) {
return configs.reduce(
(acc, fn) => {
const partial = fn()
return {
...acc,
...partial,
plugins: [...(acc.plugins || []), ...(partial.plugins || [])],
}
},
{ plugins: [] }
)
}
ts
注意:mergeConfig 只接受对象形式的配置。回调形式的配置(defineConfig((configEnv) => ...))需要先调用再传入。
模块依赖关系
base(必需)
├── router(可选,依赖 base)
├── layout(可选,依赖 router)
├── auto-import(可选,依赖 base)
└── cdn(可选,独立)
text
关键点:layout 依赖 router,router 依赖 base。合并时需要按依赖顺序组装。
方案对比
| 方案 | 描述 | 适用场景 |
|---|---|---|
| 配置函数导出 | 每个模块导出一个 get*Config() 函数 | CLI 动态合并配置 |
| 配置文件覆盖 | 使用 .ejs 模板 + replace | 静态模板生成 |
| Vite 插件组合 | 每个模块作为一个 Vite 插件 | 运行时动态加载 |
| Vite mergeConfig | 使用 mergeConfig 深度合并 | 开发时配置组合 |
实践要点
- 拆分时注意模块间的依赖关系,layout 依赖 router 的路由信息
- 每个配置模块需自带
package.json,声明该模块所需的依赖 - 模板 CLI 合并配置时,需要处理插件数组的去重和排序
vite.config.ts中的import和plugins数组是合并的重点区域mergeConfig只接受对象形式配置,回调形式需先调用再传入- 路由模块独立后使用
createRouter替代ViteSSG,降低对 layouts 的强依赖
↑